﻿using System;
using System.Collections.ObjectModel;
using BalanceManagerApp.DataAccess;
using BalanceManagerApp.Model;

namespace BalanceManagerApp.ViewModel
{
    public class FlowFundsViewModel : WorkspaceViewModel
    {
        IItemRepository itemRepository;
        IFlowFundsRepository flowFundsRepository;
        ObservableCollection<FlowFundsItem> items;
        ObservableCollection<FlowFundsItem> todayItemsList;
        ObservableCollection<FlowFundsItem> yesterdayItemsList;
        ObservableCollection<FlowFundsItem> lastWeekItemsList;
        ObservableCollection<FlowFundsItem> lastMonthItemsList;

        public FlowFundsViewModel()
        {
        }

        public FlowFundsViewModel(IItemRepository repository)
        {
            itemRepository = repository;
        }

        public IItemRepository ItemRepository
        {
            get
            {
                if (this.itemRepository == null)
                    this.itemRepository = new ItemRepository();
                return this.itemRepository;
            }
            set
            {
                this.itemRepository = value;
            }
        }

        public IFlowFundsRepository FlowFundsRepository
        {
            get
            {
                if (this.flowFundsRepository == null)
                    this.flowFundsRepository = new FlowFundsRepository();
                return this.flowFundsRepository;
            }
            set
            {
                this.flowFundsRepository = value;
            }
        }

        public ObservableCollection<FlowFundsItem> Items
        {
            get
            {
                if (items == null)
                {
                    items = new ObservableCollection<FlowFundsItem>();
                    foreach (var item in this.ItemRepository.SelectItems())
                        items.Add(new FlowFundsItem {Item = new Item(item.Name, item.Category)});
                }
                return items;
            }
        }

        public ObservableCollection<FlowFundsItem> TodayItemsList
        {
            get
            {
                if (this.todayItemsList == null)
                {
                    var now = DateTime.Now;
                    var beginDate = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0);
                    var endDate = new DateTime(now.Year, now.Month, now.Day, 23, 59, 59);
                    var list = this.FlowFundsRepository.SelectItemsForPeriod(beginDate, endDate);
                    this.todayItemsList = new ObservableCollection<FlowFundsItem>(list);
                }
                return this.todayItemsList;
            }
        }

        public ObservableCollection<FlowFundsItem> YesterdayItemsList
        {
            get
            {
                if (this.yesterdayItemsList == null)
                {
                    var end = DateTime.Now;
                    var start = end.AddDays(-1);
                    var beginDate = new DateTime(start.Year, start.Month, start.Day, 0, 0, 0);
                    var endDate = new DateTime(end.Year, end.Month, end.Day, 23, 59, 59);
                    var list = this.FlowFundsRepository.SelectItemsForPeriod(beginDate, endDate);
                    this.yesterdayItemsList = new ObservableCollection<FlowFundsItem>(list);
                }
                return this.yesterdayItemsList;
            }
        }

        public ObservableCollection<FlowFundsItem> LastWeekItemsList
        {
            get
            {
                if (this.lastWeekItemsList == null)
                {
                    var end = DateTime.Now;
                    var start = end.AddDays(-(int)end.DayOfWeek);
                    var beginDate = new DateTime(start.Year, start.Month, start.Day, 0, 0, 0);
                    var endDate = new DateTime(end.Year, end.Month, end.Day, 23, 59, 59);
                    var list = this.FlowFundsRepository.SelectItemsForPeriod(beginDate, endDate);
                    this.lastWeekItemsList = new ObservableCollection<FlowFundsItem>(list);
                }
                return this.lastWeekItemsList;
            }
        }

        public ObservableCollection<FlowFundsItem> LastMonthItemsList
        {
            get
            {
                if (this.lastMonthItemsList == null)
                {
                    var end = DateTime.Now;
                    var start = end.AddDays(-end.Day);
                    var beginDate = new DateTime(start.Year, start.Month, start.Day, 0, 0, 0);
                    var endDate = new DateTime(end.Year, end.Month, end.Day, 23, 59, 59);
                    var list = this.FlowFundsRepository.SelectItemsForPeriod(beginDate, endDate);
                    this.lastMonthItemsList = new ObservableCollection<FlowFundsItem>(list);
                }
                return this.lastMonthItemsList;
            }
        }

        void NewItemExecute(object o)
        {
            var newItem = (Item)o;
            this.items.Add(new FlowFundsItem { Item = newItem });
            this.ItemRepository.Save(newItem);
        }

        bool NewItemCanExecute(object o)
        {
            return true;
        }

        public CommandViewModel NewItem
        {
            get
            {
                var command = new RelayCommand(this.NewItemExecute, this.NewItemCanExecute);
                return new CommandViewModel("NewItem", "Resources/check.png", command);
            }
        }

        void MakeFlowFundsExecute(object o)
        {
            var itemAmount = (FlowFundsItem)o;
            this.FlowFundsRepository.AddFlowFundsItem(itemAmount.Item, itemAmount.IncomeAmount, itemAmount.ExpenseAmount, DateTime.Now);
        }

        bool MakeFlowFundsCanExecute(object o)
        {
            var itemAmount = (FlowFundsItem)o;

            if (itemAmount.IncomeAmount <= 0 && itemAmount.ExpenseAmount <= 0)
                return false;
            if (string.IsNullOrEmpty(itemAmount.Item.Name))
                return false;
            if (string.IsNullOrEmpty(itemAmount.Item.Category))
                return false;

            return true;
        }

        public CommandViewModel MakeFlowFunds
        {
            get
            {
                var command = new RelayCommand(MakeFlowFundsExecute, MakeFlowFundsCanExecute);
                return new CommandViewModel("Make Income", "", command);
            }
        }
    }
}
